import express, { json, Request, Response } from 'express';
import { echo } from './newecho';
import morgan from 'morgan';
import config from './config.json';
import cors from 'cors';
import YAML from 'yaml';
import sui from 'swagger-ui-express';
import fs from 'fs';
import path from 'path';
import process from 'process';
import { data, getData, setData } from './dataStore';
import { adminQuizInfo, adminQuizCreate, adminQuizList, adminQuizRemove, adminQuizNameUpdate, adminQuizDescriptionUpdate, adminTrashView, adminTrashRestore } from './quiz';
import { clear } from './other';
import { trashEmpty } from './trashEmpty';
import { transferQuizToAnother } from './transferQuiz';
import { adminAuthLogin, adminAuthLogout, adminAuthRegister, adminUserDetails } from './auth';
import { adminUserDetailsUpdate, adminUserPasswordUpdate } from './user';
import { DeleteQuestion, MoveQuestion } from './question';
import { createQuizQuestion, getFinalResults, generateCSV,  generateUniqueName, findSessionByPlayerId, salt ,hashPassword} from './xuedingefunction';
import { isValidToken } from './check';
import { QuestionInput, Questions } from './interface';



// Set up web app
const app = express();
// Use middleware that allows us to access the JSON body of requests
app.use(json());
// Use middleware that allows for access from other domains
app.use(cors());
// for logging errors (print to terminal)
app.use(morgan('dev'));
// for producing the docs that define the API
const file = fs.readFileSync(path.join(process.cwd(), 'swagger.yaml'), 'utf8');
app.get('/', (req: Request, res: Response) => res.redirect('/docs'));
app.use('/docs', sui.serve, sui.setup(YAML.parse(file), { swaggerOptions: { docExpansion: config.expandDocs ? 'full' : 'list' } }));

const PORT: number = parseInt(process.env.PORT || config.port);
const HOST: string = process.env.IP || '0.0.0.0';

// ====================================================================
//  ================= WORK IS DONE BELOW THIS LINE ===================
// ====================================================================

// Example get request
app.get('/echo', (req: Request, res: Response) => {
  const data = req.query.echo as string;
  return res.json(echo(data));
});

const load = () => {
  if (fs.existsSync('./database.json')) {
    const file = fs.readFileSync('./database.json', { encoding: 'utf8' });
    setData(JSON.parse(file));
  }
};
load();



app.post('/v1/admin/auth/register', async (req: Request, res: Response) => {
  const { email, password, nameFirst, nameLast } = req.body;
  try {
    const hashedPassword = await hashPassword(password);
    console.log("hashedPassword", hashedPassword)

    const response = adminAuthRegister(email, hashedPassword, nameFirst, nameLast);

    if ('error' in response) {
      return res.status(400).json(response);
    }

    return res.status(200).json(response);
  } catch (err) {
    return res.status(500).json({ error: 'Internal server error' });
  }
});

app.post('/v1/admin/auth/login', async (req: Request, res: Response) => {
  const { email, password } = req.body;
  const hashedPassword = await hashPassword(password);
  console.log("hashedPassword", hashedPassword)
  const response = adminAuthLogin(email, hashedPassword);

  if ('error' in response) {
    return res.status(400).json(response);
  }

  return res.status(200).json(response);
});

app.get('/v1/admin/user/details', (req: Request, res: Response) => {
  const token = req.query.token as string;
  const response = adminUserDetails(token);

  if ('error' in response) {
    return res.status(401).json(response);
  }

  return res.status(200).json(response);
});

app.put('/v1/admin/user/details', (req: Request, res: Response) => {
  const { token, email, nameFirst, nameLast } = req.body;
  const response = adminUserDetailsUpdate(token, email, nameFirst, nameLast);

  if ('error' in response) {
    if (response.error === 'Token is empty or invalid (does not refer to valid logged in user session)') {
      return res.status(401).json(response);
    } else {
      return res.status(400).json(response);
    }
  }

  return res.status(200).json(response);
});

app.put('/v1/admin/user/password', (req: Request, res: Response) => {
  const { token, oldPassword, newPassword } = req.body;
  const response = adminUserPasswordUpdate(token, oldPassword, newPassword);

  if ('error' in response) {
    if (response.error === 'Token is empty or invalid (does not refer to valid logged in user session)') {
      return res.status(401).json(response);
    } else {
      return res.status(400).json(response);
    }
  }

  return res.status(200).json(response);
});

app.get('/v1/admin/quiz/list', (req: Request, res: Response) => {
  const token = req.query.token as string;
  const response = adminQuizList(token);

  if ('error' in response) {
    return res.status(401).json(response);
  }

  return res.status(200).json(response);
});

app.post('/v1/admin/quiz', (req: Request, res: Response) => {
  const { token, name, description } = req.body;
  const response = adminQuizCreate(token, name, description);

  if ('error' in response) {
    if (response.error === 'Token is empty or invalid (does not refer to valid logged in user session)') {
      return res.status(401).json(response);
    } else {
      return res.status(400).json(response);
    }
  }

  return res.status(200).json(response);
});

app.delete('/v1/admin/quiz/:quizid', (req: Request, res: Response) => {
  const quizId = parseInt(req.params.quiz);
  const token = req.query.token as string;
  const response = adminQuizRemove(token, quizId);

  if ('error' in response) {
    if (response.error === 'Token is empty or invalid (does not refer to valid logged in user session)') {
      return res.status(401).json(response);
    } else if (response.error === 'Quiz ID does not refer to a quiz that this user owns.') {
      return res.status(403).json(response);
    } else {
      return res.status(400).json(response);
    }
  }

  return res.status(200).json(response);
});

app.get('/v1/admin/quiz/:quizid', (req: Request, res: Response) => {
  const quizId = parseInt(req.params.quizid);
  const token = req.query.token as string;
  const response = adminQuizInfo(token, quizId);

  if ('error' in response) {
    if (response.error === 'Token is empty or invalid (does not refer to valid logged in user session)') {
      return res.status(401).json(response);
    } else if (response.error === 'Quiz ID does not refer to a quiz that this user owns.') {
      return res.status(403).json(response);
    }
  }

  return res.status(200).json(response);
});

app.put('/v1/admin/quiz/:quizid/name', (req: Request, res: Response) => {
  const quizId = parseInt(req.params.quizid);
  const { token, name } = req.body;
  const response = adminQuizNameUpdate(token, quizId, name);

  if ('error' in response) {
    if (response.error === 'Token is empty or invalid (does not refer to valid logged in user session)') {
      return res.status(401).json(response);
    } else if (response.error === 'Quiz ID does not refer to a quiz that this user owns.') {
      return res.status(403).json(response);
    } else {
      return res.status(400).json(response);
    }
  }

  return res.status(200).json(response);
});

app.put('/v1/admin/quiz/:quiz/description', (req: Request, res: Response) => {
  const quizId = parseInt(req.params.quizid);
  const { token, description } = req.body;
  const response = adminQuizDescriptionUpdate(token, quizId, description);

  if ('error' in response) {
    if (response.error === 'Token is empty or invalid (does not refer to valid logged in user session)') {
      return res.status(401).json(response);
    } else if (response.error === 'Quiz ID does not refer to a quiz that this user owns.') {
      return res.status(403).json(response);
    } else {
      return res.status(400).json(response);
    }
  }

  return res.status(200).json(response);
});

app.delete('/v1/clear', (req: Request, res: Response) => {
  clear();

  return res.status(200).json({});
});

app.delete('/v1/admin/quiz/trash/empty', (req: Request, res: Response) => {
  const token = req.query.token as string;
  const quizIds = JSON.parse(req.query.quizIds as string) as number[];
  const response = trashEmpty(token, quizIds);

  if ('error' in response) {
    if (response.error === 'Token is empty or invalid (does not refer to valid logged in user session)') {
      return res.status(401).json(response);
    } else if (response.error === 'Quiz ID does not refer to a quiz that this user owns.') {
      return res.status(403).json(response);
    } else {
      return res.status(400).json(response);
    }
  }

  return res.status(200).json(response);
});

app.post('/v1/admin/quiz/:quizid/transfer', (req: Request, res: Response) => {
  const { token, userEmail } = req.body;
  const quizId = parseInt(req.params.quizid);
  const response = transferQuizToAnother(token, userEmail, quizId);

  if ('error' in response) {
    if (response.error === 'Token is empty or invalid (does not refer to valid logged in user session)') {
      return res.status(401).json(response);
    } else if (response.error === 'Quiz ID does not refer to a quiz that this user owns.') {
      return res.status(403).json(response);
    } else {
      return res.status(400).json(response);
    }
  }

  return res.status(200).json(response);
});


app.post('/v1/admin/auth/logout', (req: Request, res: Response) => {
  const token = req.headers["authorization"] as string;
  let data = getData()
  const response = adminAuthLogout(token);

  if ('error' in response) {
    return res.status(400).json({ error: "Token is empty or invalid (does not refer to valid logged in user quiz session)" });      // return res.status(401).json(response);
  }

  return res.status(200).json(response);
});


app.post('/v1/admin/quiz/:quizid/restore', (req: Request, res: Response) => {
  const { token } = req.body;
  const { quizid } = req.params;
  let num = Number(quizid);
  const response = adminTrashRestore(token, num);

  if ('error' in response) {
    if (response.error === 'Token is empty or invalid (does not refer to valid logged in user session)') {
      return res.status(401).json(response);
    } else if (response.error === 'Valid token is provided, but user is not an owner of this quiz') {
      return res.status(403).json(response);
    } else {
      return res.status(400).json(response);
    }
  }

  return res.status(200).json(response);
});

app.delete('/v1/admin/quiz/:quizid/question/:questionid', (req: Request, res: Response) => {
  const { token } = req.body;
  const { quizid, questionid } = req.params;
  let num = Number(quizid);
  let num_1 = Number(questionid);
  const response = DeleteQuestion(token, num, num_1);

  if ('error' in response) {
    if (response.error === 'Token is empty or invalid (does not refer to valid logged in user session)') {
      return res.status(401).json(response);
    } else if (response.error === 'Valid token is provided, but user is not an owner of this quiz') {
      return res.status(403).json(response);
    } else {
      return res.status(400).json(response);
    }
  }

  return res.status(200).json(response);
});

app.put('/v1/admin/quiz/:quizid/question/:questionid/move', (req: Request, res: Response) => {
  const { token, newposition } = req.body;
  const { quizid, questionid } = req.params;
  let num = Number(quizid);

  const response = MoveQuestion(token, num, questionid, newposition);

  if ('error' in response) {
    if (response.error === 'Token is empty or invalid (does not refer to valid logged in user session)') {
      return res.status(401).json(response);
    } else if (response.error === 'Valid token is provided, but user is not an owner of this quiz') {
      return res.status(403).json(response);
    } else {
      return res.status(400).json(response);
    }
  }

  return res.status(200).json(response);

});

app.get('/v1/admin/quiz/trash', (req: Request, res: Response) => {
  const { token } = req.body;
  const response = adminTrashView(token);

  if ('error' in response) {
    return res.status(401).json(response);
  }

  return res.status(200).json(response);
});


app.put('/v1/admin/quiz/:quizid/description', (req: Request, res: Response) => {
  const { token, description } = req.body;
  const { quizid } = req.params;
  if (!token || !isValidToken(token)) {
    return res.status(401).json({ error: 'Token is empty or invalid (does not refer to valid logged in user session)' });
  }

  if (description.length > 100) {
    return res.status(400).json({ error: 'Description is more than 100 characters in length' });
  }

  // Verify ownership and update description
  const data = getData();
  const quiz = data.quizzes.find(q => q.QuizID === Number(quizid));
  if (!quiz) {
    return res.status(404).json({ error: 'Quiz not found' });
  }
  quiz.Description = description;
  setData(data);

  res.status(200).json({});
});

app.get('/v1/admin/quiz/trash', (req: Request, res: Response) => {
  const { token } = req.body;
  if (!token || !isValidToken(token)) {
    return res.status(401).json({ error: 'Token is empty or invalid (does not refer to valid logged in user session)' });
  }

  // Return quizzes that are in the trash state
  const data = getData();
  const trashQuizzes = data.quizzes.filter(q => q.State === 'TRASH');
  res.status(200).json({ quizzes: trashQuizzes });
});



// 恢复已删除的测验

// API 恢复测验
app.post('/v1/admin/quiz/:quizid/restore', (req: Request, res: Response) => {
  const { token } = req.body;
  const { quizid } = req.params;
  let num = Number(quizid);
  const response = adminTrashRestore(token, num);

  if ('error' in response) {
    if (response.error.includes('Token is empty or invalid')) {
      return res.status(401).json(response);
    } else if (response.error.includes('not an owner')) {
      return res.status(403).json(response);
    } else {
      return res.status(400).json(response);
    }
  }

  return res.status(200).json(response);
});

// API 查看回收站测验
app.get('/v1/admin/quiz/trash', (req: Request, res: Response) => {
  const { token } = req.query as any;
  if (!token || !isValidToken(token)) {
    return res.status(401).json({ error: 'Token is empty or invalid' });
  }

  let userId = isValidToken(token);
  if (!userId) {
    return res.status(401).json({ error: 'Invalid token' });
  }

  const data = getData();
  const trashedQuizzes = data.quizzes.filter(q => q.State === 'TRASHED' && q.AuthorID.includes(userId));

  return res.status(200).json({ quizzes: trashedQuizzes });
});



app.post('/v1/admin/quiz/:quizid/question', (req: Request, res: Response) => {
  const { token } = req.body;
  const { quizid } = req.params;
  const questionData: QuestionInput = req.body.questionData;

  const response = createQuizQuestion(token, Number(quizid), questionData);

  if ('error' in response) {
    switch (response.error) {
      case 'Token is empty or invalid (does not refer to valid logged in user session)':
        return res.status(401).json(response);
      case 'Valid token is provided, but user is not an owner of this quiz':
        return res.status(403).json(response);
      default:
        return res.status(400).json(response);
    }
  }

  return res.status(200).json(response);
});


// 删除特定测验中的问题
app.delete('/v1/admin/quiz/:quizid/question/:questionid', (req: Request, res: Response) => {
  const { quizid, questionid, token } = req.params;
  // 检查Token有效性和权限
  const userId = isValidToken(token);
  if (!userId) {
    return res.status(401).json({ error: 'Token is empty or invalid (does not refer to valid logged in user session)' });
  }

  // 获取数据
  const data = getData();
  const quiz = data.quizzes.find(q => q.QuizID === Number(quizid));

  if (!quiz || !quiz.AuthorID.includes(userId)) {
    return res.status(403).json({ error: 'Valid token is provided, but user is not an owner of this quiz' });
  }

  const questionIndex = quiz.Questions.findIndex((q: Questions) => q.questionId === Number(questionid));
  if (questionIndex === -1) {
    return res.status(400).json({ error: 'Question Id does not refer to a valid question within this quiz' });
  }

  // 执行删除操作
  quiz.Questions.splice(questionIndex, 1);
  quiz.TimeLastEdited = new Date();
  setData(data); // 更新数据

  return res.status(200).json({ message: 'Question deleted successfully' });
});

// 复制特定测验中的问题
app.post('/v1/admin/quiz/:quizid/question/:questionid/duplicate', (req: Request, res: Response) => {
  const { quizid, questionid } = req.params;
  const { token } = req.body;

  // 检查Token有效性和权限
  const userId = isValidToken(token);
  if (!userId) {
    return res.status(401).json({ error: 'Token is empty or invalid (does not refer to valid logged in user session)' });
  }

  // 获取数据
  const data = getData();
  const quiz = data.quizzes.find(q => q.QuizID === Number(quizid));

  if (!quiz || !quiz.AuthorID.includes(userId)) {
    return res.status(403).json({ error: 'Valid token is provided, but user is not an owner of this quiz' });
  }

  const question = quiz.Questions.find((q: Questions) => q.questionId === Number(questionid));
  if (!question) {
    return res.status(400).json({ error: 'Question Id does not refer to a valid question within this quiz' });
  }

  // 执行复制操作
  const newQuestion = { ...question, questionId: Math.max(...quiz.Questions.map((q: Questions) => q.questionId)) + 1 };
  quiz.Questions.push(newQuestion);
  quiz.TimeLastEdited = new Date();
  setData(data); // 更新数据

  return res.status(200).json({ duplicatedQuestion: newQuestion });
});

app.post('/v2/admin/auth/logout', (req: Request, res: Response) => {
  const { token } = req.body; // 从请求体中获取token

  // 首先验证Token是否有效
  if (!token || !isValidToken(token)) {
    return res.status(401).json({ error: 'Token is empty or invalid (does not refer to valid logged in user quiz session)' });
  }

  // 调用登出函数
  const response = adminAuthLogout(token);
  if ('error' in response) {
    return res.status(401).json(response);
  }

  // 登出成功，返回200状态码
  return res.status(200).json({});
});

app.put('/v1/admin/quiz/:quizid/thumbnail', (req: Request, res: Response) => {
  const { quizid } = req.params;
  const { token } = req.headers;
  const { imgUrl } = req.body;

  // 检查token是否有效
  const userId = isValidToken(token as string);
  if (!userId) {
    return res.status(401).json({ error: 'Token is empty or invalid (does not refer to valid logged in user session)' });
  }

  // 验证imgUrl格式
  if (!/^https?:\/\/.*\.(jpg|jpeg|png)$/i.test(imgUrl)) {
    return res.status(400).json({
      error: 'The imgUrl does not end with one of the following filetypes (case insensitive): jpg, jpeg, png or does not begin with \'http://\' or \'https://\''
    });
  }

  const data = getData();
  const quiz = data.quizzes.find(q => q.QuizID === Number(quizid));

  // 检查测验是否存在以及用户是否为测验的所有者
  if (!quiz) {
    return res.status(404).json({ error: 'Quiz not found' });
  }
  if (!quiz.AuthorID.includes(userId)) {
    return res.status(403).json({ error: 'Valid token is provided, but user is not an owner of this quiz' });
  }

  // 更新缩略图URL和编辑时间
  quiz.thumbnailUrl = imgUrl;
  quiz.TimeLastEdited = new Date();

  setData(data);
  res.status(200).json({});
});

app.get('/v1/admin/quiz/:quizid/sessions', (req: Request, res: Response) => {
  const token = req.headers['authorization'];
  const quizId = parseInt(req.params.quizid);

  if (!token || isValidToken(token) === null) {
    return res.status(401).json({ error: 'Token is empty or invalid (does not refer to valid logged in user session)' });
  }

  const userId = isValidToken(token);
  const data = getData();
  const userQuizzes = data.users.find(user => user.userID === userId)?.QuizID || [];

  if (!userQuizzes.includes(quizId)) {
    return res.status(403).json({ error: 'Valid token is provided, but user is not an owner of this quiz' });
  }

  const quizzes = data.quizzes.find(quiz => quiz.QuizID === quizId);
  if (!quizzes) {
    return res.status(404).json({ error: 'Quiz not found' });
  }

  const activeSessions = quizzes.Sessions.filter(session => session.State !== 'END').sort((a, b) => a.SessionID - b.SessionID);
  const inactiveSessions = quizzes.Sessions.filter(session => session.State === 'END').sort((a, b) => a.SessionID - b.SessionID);

  res.status(200).json({ activeSessions, inactiveSessions });
});

app.post('/v1/admin/quiz/:quizid/session/start', (req: Request, res: Response) => {
  const { token } = req.body;
  const quizId = parseInt(req.params.quizid);

  if (!token || isValidToken(token) === null) {
    return res.status(401).json({ error: 'Token is empty or invalid (does not refer to valid logged in user session)' });
  }

  const userId = isValidToken(token);
  const data = getData();
  const userQuizzes = data.users.find(user => user.userID === userId)?.QuizID || [];

  if (!userQuizzes.includes(quizId)) {
    return res.status(403).json({ error: 'Valid token is provided, but user is not an owner of this quiz' });
  }

  const quiz = data.quizzes.find(q => q.QuizID === quizId);
  if (!quiz || quiz.State === 'TRASH') {
    return res.status(400).json({ error: 'The quiz does not exist or is in trash' });
  }

  // 实现测验会话启动逻辑...
  res.status(200).json({ message: 'Session started successfully' });
});

app.put('/v1/admin/quiz/:quizid/session/:sessionid', (req: Request, res: Response) => {
  const token = req.headers['authorization'];
  const quizId = parseInt(req.params.quizid);
  const sessionId = parseInt(req.params.sessionid);
  const { action } = req.body;

  if (!token || isValidToken(token) === null) {
    return res.status(401).json({ error: 'Token is empty or invalid (does not refer to valid logged in user session)' });
  }

  res.status(200).json({ message: 'Session updated successfully' });
});


app.get('/v1/admin/quiz/:quizid/session/:sessionid/results', (req: Request, res: Response) => {
  const token = req.headers['authorization'];
  const quizId = parseInt(req.params.quizid);
  const sessionId = parseInt(req.params.sessionid);

  if (!token || isValidToken(token) === null) {
    return res.status(401).json({ error: 'Token is empty or invalid (does not refer to valid logged in user session)' });
  }

  const userId = isValidToken(token);
  const data = getData();
  const quiz = data.quizzes.find(q => q.QuizID === quizId);

  if (!quiz || !quiz.AuthorID.includes(userId)) {
    return res.status(403).json({ error: 'Valid token is provided, but user is not an owner of this quiz' });
  }

  const session = quiz.Sessions.find(s => s.SessionID === sessionId);
  if (!session) {
    return res.status(400).json({ error: 'Session Id does not refer to a valid session within this quiz' });
  }

  if (session.State !== 'END') {
    return res.status(400).json({ error: 'Session is not in FINAL_RESULTS state' });
  }

  const results = getFinalResults(sessionId);
  res.status(200).json({ results });
});

app.get('/v1/admin/quiz/:quizid/session/:sessionid/results/csv', (req: Request, res: Response) => {
  const token = req.headers['authorization'];
  const quizId = parseInt(req.params.quizid);
  const sessionId = parseInt(req.params.sessionid);

  if (!token || isValidToken(token) === null) {
    return res.status(401).json({ error: 'Token is empty or invalid (does not refer to valid logged in user session)' });
  }

  const userId = isValidToken(token);
  const data = getData();
  const quiz = data.quizzes.find(q => q.QuizID === quizId);

  if (!quiz || !quiz.AuthorID.includes(userId)) {
    return res.status(403).json({ error: 'Valid token is provided, but user is not an owner of this quiz' });
  }

  const session = quiz.Sessions.find(s => s.SessionID === sessionId);
  if (!session) {
    return res.status(400).json({ error: 'Session Id does not refer to a valid session within this quiz' });
  }

  if (session.State !== 'END') {
    return res.status(400).json({ error: 'Session is not in FINAL_RESULTS state' });
  }

  // 生成CSV结果
  const csvLink = generateCSV(sessionId);
  res.status(200).json({ csvLink });
});

app.post('/v1/player/join', (req: Request, res: Response) => {
  const { name, sessionId } = req.body;
  const data = getData();
  const session = data.quizzes.flatMap(quiz => quiz.Sessions).find(session => session.SessionID === sessionId);
  // if (session.State !== 'LOBBY') {

  if (!session || session.State !== 'LOBBY') {
    return res.status(400).json({ error: 'Session ID does not refer to a valid session or session is not in LOBBY state' });
  }

  let playerName = name.trim();
  if (playerName === '') {
    playerName = generateUniqueName();
  } else if (data.users.some(u => u.FirstName === playerName)) {
    return res.status(400).json({ error: 'Name of user entered is not unique' });
  }

  // 创建一个新的用户，可以自由加入
  const newUser = {
    userID: Math.max(...data.users.map(u => u.userID)) + 1,
    QuizID: [] as number[],
    FirstName: playerName,
    LastName: '',
    email: '',
    password: '',
    usedPasswords: [] as string[],
    numSuccessfulLogins: 0,
    numFailedPasswordsSinceLastLogin: 0,
  };
  data.users.push(newUser);
  setData(data);

  return res.status(200).json({ playerId: newUser.userID, name: newUser.FirstName });
});


app.get('/v1/player/:playerid', (req: Request, res: Response) => {
  const { playerid } = req.params;
  const data = getData();
  const user = data.users.find(user => user.userID === Number(playerid));

  if (!user) {
    return res.status(400).json({ error: 'Player ID does not exist' });
  }


  return res.status(200).json({ playerStatus: { userID: user.userID, FirstName: user.FirstName, numLogins: user.numSuccessfulLogins } });
});


app.get('/v1/player/:playerid/question/:questionposition', (req: Request, res: Response) => {
  const { playerid, questionposition } = req.params;
  const data = getData();
  const user = data.users.find(u => u.userID === Number(playerid));
  console.log("user", user)
  if (!user) {
    return res.status(400).json({ error: 'Player ID does not exist' });
  }

  // 找到用户所在的会话
  const session = data.quizzes.flatMap(quiz => quiz.Sessions).find(session => session.Results?.some(r => r.playerId === Number(playerid)));

  if (!session) {
    return res.status(400).json({ error: 'Session does not exist for this player' });
  }
  console.log("data.quizzes", data.quizzes)
  console.log("session.QuizID", session.QuizID)


  // 找到对应的测验
  const quiz = data.quizzes.find(quiz => quiz.QuizID === session.QuizID);
  // const quiz = data.quizzes.find(quiz => quiz.QuizID === session.QuizID);

  if (!quiz) {
    return res.status(400).json({ error: 'Quiz does not exist for this session' });
  }

  // if (session.State === 'LOBBY' || session.State === 'QUESTION_COUNTDOWN' || session.State === 'END') {
  //   return res.status(400).json({ error: 'Invalid session state' });
  // }
  console.log("data.quizzes", data.quizzes)

  const questionIndex = Number(questionposition) - 1;
  const question = data.quizzes[questionIndex];

  if (!question) {
    return res.status(400).json({ error: 'Question position is not valid for the session this player is in' });
  }

  // 返回问题信息
  return res.status(200).json({ question });
});
app.put('/v1/player/:playerid/question/:questionposition/answer', (req: Request, res: Response) => {
  const { playerid, questionposition } = req.params;
  const { answers } = req.body;
  const data = getData();
  console.log("playerid =>", playerid)

  const session = findSessionByPlayerId(data, Number(playerid));
  console.log("QUESTION_OPEN _session =>", session)
  // if (!session || session.State !== 'QUESTION_OPEN') {
  if (!session || session.State !== 'QUESTION_OPEN') {
    return res.status(400).json({ error: 'Session is not in QUESTION_OPEN state or does not exist' });
    // return res.status(400).json({});
  }

  return res.status(200).json({});
  // return res.status(200).json({ message: 'Answer submitted successfully' });
});



app.get('/v1/player/:playerid/question/:questionposition/results', (req: Request, res: Response) => {
  const { playerid, questionposition } = req.params;
  const data = getData();
  const session = findSessionByPlayerId(data, Number(playerid));

  if (!session || session.State !== 'ANSWER_SHOW') {
    return res.status(400).json({ error: 'Session is not in ANSWER_SHOW state or question position is invalid' });
  }

  // 直接返回问题的结果
  const results = session.Results?.find(r => r.playerId === Number(playerid));
  return res.status(200).json({ results });
});


app.get('/v1/player/:playerid/results', (req: Request, res: Response) => {
  const { playerid } = req.params;
  const data = getData();
  const session = findSessionByPlayerId(data, Number(playerid));
  console.log("session =>", session)

  if (!session || session.State !== 'FINAL_RESULTS') {

    return res.status(400).json({ error: 'Session is not in FINAL_RESULTS state' });
  }

  // 直接返回整个会话的结果
  return res.status(200).json({ finalResults: session.Results });
});

app.get('/v1/player/:playerid/chat', (req: Request, res: Response) => {
  const { playerid } = req.params;
  const data = getData();
  const session = findSessionByPlayerId(data, Number(playerid));
  if (!session) {
    return res.status(400).json({ error: 'Player ID does not exist or is not part of any session' });
  }
  const messages = session.Messages || [];

  return res.status(200).json({ messages });
});

app.post('/v1/player/:playerid/chat', (req: Request, res: Response) => {
  const { playerid } = req.params;
  const { message } = req.body;
  const data = getData();
  const session = findSessionByPlayerId(data, Number(playerid));

  if (!session) {
    return res.status(400).json({ error: 'Player ID does not exist or is not part of any session' });
  }

  if (message.length < 1 || message.length > 100) {
    return res.status(400).json({ error: 'Message body must be between 1 and 100 characters' });
  }

  const newMessage = {
    senderId: Number(playerid),
    message: message,
    timeSent: Math.floor(Date.now() / 1000)
  };

  // 添加消息到会话
  session.Messages = session.Messages || [];
  session.Messages.push(newMessage);

  setData(data);  // 更新数据存储

  return res.status(200).json({ message: 'Message sent successfully' });
});



app.get('/v1/admin/quiz/:quizid/session/:sessionid', (req: Request, res: Response) => {
  const { token } = req.headers;
  const { quizid, sessionid } = req.params;

  if (!token) {
    return res.status(401).json({ error: 'Token is required' });
  }

  // const authError = adminAuthCheck(token, Number(quizid));
  // if (authError) {
  //   return res.status(authError.startsWith('Token') ? 401 : 403).json({ error: authError });
  // }

  const data = getData();
  const quiz = data.quizzes.find(q => q.QuizID === Number(quizid));
  const session = quiz?.Sessions.find(s => s.SessionID === Number(sessionid));

  if (!session) {
    return res.status(400).json({ error: 'Session ID does not refer to a valid session within this quiz' });
  }

  return res.status(200).json({ session });
});

const port = 3000;
app.listen(port, () => {
  console.log(`Server running on port ${port}`);
});

// ====================================================================
//  ================= WORK IS DONE ABOVE THIS LINE ===================
// ====================================================================

app.use((req: Request, res: Response) => {
  const error = `
    Route not found - This could be because:
      0. You have defined routes below (not above) this middleware in server.ts
      1. You have not implemented the route ${req.method} ${req.path}
      2. There is a typo in either your test or server, e.g. /posts/list in one
         and, incorrectly, /post/list in the other
      3. You are using ts-node (instead of ts-node-dev) to start your server and
         have forgotten to manually restart to load the new changes
      4. You've forgotten a leading slash (/), e.g. you have posts/list instead
         of /posts/list in your server.ts or test file
  `;
  res.json({ error });
});

// start server
const server = app.listen(PORT, HOST, () => {
  // DO NOT CHANGE THIS LINE
  console.log(`⚡️ Server started on port ${PORT} at ${HOST}`);
});

// For coverage, handle Ctrl+C gracefully
process.on('SIGINT', () => {
  server.close(() => console.log('Shutting down server gracefully.'));
});
